package io.kiki.sba.registry.server.data_store.bootstrap;

import io.kiki.sba.registry.common.model.slot.filter.MultiSyncDataAcceptorManager;
import io.kiki.sba.registry.server.data_store.multi.cluster.client.handler.RemoteDataChangeNotifyHandler;
import io.kiki.sba.registry.server.data_store.multi.cluster.dataserver.handler.MultiClusterSlotDiffDigestRequestHandler;
import io.kiki.sba.registry.server.data_store.multi.cluster.dataserver.handler.MultiClusterSlotDiffPublisherRequestHandler;
import io.kiki.sba.registry.server.data_store.multi.cluster.exchanger.RemoteDataNodeExchanger;
import io.kiki.sba.registry.server.data_store.multi.cluster.executor.MultiClusterExecutorManager;
import io.kiki.sba.registry.server.data_store.multi.cluster.slot.MultiClusterSlotManager;
import io.kiki.sba.registry.server.data_store.multi.cluster.slot.MultiClusterSlotManagerImpl;
import io.kiki.sba.registry.server.data_store.multi.cluster.storage.MultiClusterDatumService;
import io.kiki.sba.registry.server.shared.remoting.AbstractClientHandler;
import io.kiki.sba.registry.server.shared.remoting.AbstractServerHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.Collection;


@Configuration
@EnableConfigurationProperties
public class MultiClusterDataConfiguration {

    @Configuration
    public static class RemoteDataConfigConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public MultiClusterDataServerConfigBean multiClusterDataServerConfig() {
            return new MultiClusterDataServerConfigBean();
        }

        @Bean
        public MultiClusterExecutorManager multiClusterExecutorManager(MultiClusterDataServerConfig multiClusterDataServerConfig) {
            return new MultiClusterExecutorManager(multiClusterDataServerConfig);
        }
    }

    @Configuration
    public static class RemoteClusterExchangerConfiguration {

        @Bean
        public RemoteDataNodeExchanger remoteDataNodeExchanger() {
            return new RemoteDataNodeExchanger();
        }

        @Bean(name = "remoteDataServerHandlers")
        public Collection<AbstractServerHandler> remoteDataServerHandlers() {
            Collection<AbstractServerHandler> list = new ArrayList<>();
            list.add(multiClusterSlotDiffDigestRequestHandler());
            list.add(multiClusterSlotDiffPublisherRequestHandler());
            return list;
        }

        @Bean(name = "remoteDataClientHandlers")
        public Collection<AbstractClientHandler> remoteDataClientHandlers() {
            Collection<AbstractClientHandler> list = new ArrayList<>();
            list.add(remoteDataChangeNotifyHandler());
            return list;
        }

        @Bean
        public AbstractServerHandler multiClusterSlotDiffDigestRequestHandler() {
            return new MultiClusterSlotDiffDigestRequestHandler();
        }

        @Bean
        public AbstractServerHandler multiClusterSlotDiffPublisherRequestHandler() {
            return new MultiClusterSlotDiffPublisherRequestHandler();
        }

        @Bean
        public AbstractClientHandler remoteDataChangeNotifyHandler() {
            return new RemoteDataChangeNotifyHandler();
        }
    }

    @Configuration
    public static class RemoteDataStorageConfiguration {

        @Bean
        @ConditionalOnMissingBean
        public MultiClusterSlotManager multiClusterSlotManager() {
            return new MultiClusterSlotManagerImpl();
        }

        @Bean
        public MultiSyncDataAcceptorManager multiSyncDataAcceptorManager() {
            return new MultiSyncDataAcceptorManager();
        }

        @Bean
        public MultiClusterDatumService multiClusterDatumService() {
            return new MultiClusterDatumService();
        }
    }
}
